<template>
  <div class="app-container">
    <el-tabs
      v-model="activeName"
      type="card"
      @tab-click="handleClick"
      @tab-add="addTopNode"
      :addable="true"
      @tab-remove="removeTab"
      :closable="false"
    >
      <el-tab-pane v-for="t in tabs" :label="t.title" :name="t.id">
        <div>
          <!-- <div style="margin-left: 0px;margin-bottom:3px;">
            <el-button type="primary" size="small" @click="addTopNode()" icon="el-icon-plus">新增顶级菜单</el-button>
          </div>-->
          <el-table
            :data="routes"
            :header-cell-style="{background:'#eef1f6',color:'#606266'}"
            style="width: 100%;margin-bottom: 20px;"
            row-key="id"
            border
            default-expand-all
            :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
          >
            <el-table-column label="菜单名称">
              <template slot-scope="scope">
                <i :class="scope.row.meta.icon" :title="scope.row.meta.icon"></i>
                &nbsp;{{ scope.row.title }}
              </template>
            </el-table-column>
            <el-table-column label="菜单标识">
              <template slot-scope="scope">{{ scope.row.code }}</template>
            </el-table-column>
            <el-table-column label="菜单路由">
              <template slot-scope="scope">{{ scope.row.path }}</template>
            </el-table-column>
            <el-table-column label="重定向路径">
              <template slot-scope="scope">{{ scope.row.redirect }}</template>
            </el-table-column>
            <el-table-column label="组件地址">
              <template slot-scope="scope">{{ scope.row.component }}</template>
            </el-table-column>
            <el-table-column label="是否显示为左侧菜单">
              <template slot-scope="scope">{{ scope.row.meta.noCache |cacheFilter }}</template>
            </el-table-column>
            <el-table-column align="center" label="操作" width="180">
              <template slot-scope="scope">
                <el-button type="text" size="mini" @click="addSubNode(scope)" icon="el-icon-plus">添加</el-button>
                <el-button type="text" size="mini" @click="handleEdit(scope)" icon="el-icon-edit">编辑</el-button>
                <el-button
                  :disabled="scope.row.parentId =='00000000-0000-0000-0000-000000000000'"
                  type="text"
                  size="mini"
                  @click="handleDelete(scope)"
                  icon="el-icon-delete"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-tab-pane>
    </el-tabs>

    <el-dialog
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
      :title="dialogType==='edit'?'编辑':'新增'"
      width="60%"
      top="10vh"
    >
      <el-form
        ref="model"
        :rules="rules"
        :label-position="labelPosition"
        :model="model"
        label-width="100px"
        style="width: 90%;"
      >
        <el-row>
          <el-col :span="24">
            <el-form-item label="父级菜单" prop="parentId">
              <el-input v-model="model.parentName" placeholder="请输入父级菜单名称" :disabled="true" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="菜单名称" prop="title">
              <el-input v-model="model.title" placeholder="请输入菜单名称" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="菜单标识" prop="title">
              <el-input v-model="model.code" placeholder="请输入菜单标识" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="菜单路由" prop="path">
              <el-input v-model="model.path" placeholder="请输入菜单路由" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单重定向" prop="redirect">
              <el-input v-model="model.redirect" placeholder="请输入重定向" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="排序号" prop="sort">
              <el-input-number v-model="model.sort" style="width: 100%;"></el-input-number>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="类型" prop="type">
              <el-select
                v-model="model.type"
                class="filter-item"
                placeholder="请输入资源请求类型"
                style="width: 100%;"
              >
                <el-option
                  v-for="item in typeOptions"
                  :key="item"
                  :label="item | typeFilter"
                  :value="item"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="菜单图标" prop="icon">
              <el-input v-model="model.meta.icon" placeholder="请输入图标名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否显示" prop="icon">
              <el-select
                v-model="model.meta.noCache"
                class="filter-item"
                placeholder="是否在左侧菜单显示"
                style="width: 100%;"
              >
                <el-option
                  v-for="item in cacheOptions"
                  :key="item"
                  :label="item | cacheFilter"
                  :value="item"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="组件地址" prop="component">
              <el-input v-model="model.component" placeholder="组件地址" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input
                :autosize="{ minRows: 4, maxRows: 9}"
                v-model="model.remark"
                type="textarea"
                placeholder="备注"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div style="text-align:right;">
        <el-button type="danger" @click="dialogVisible=false">取消</el-button>
        <el-button type="primary" @click="confirmModel">提交</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { deepClone } from "@/utils";
import {
  getRoutes,
  addMenu,
  updateMenu,
  deleteMenu,
  getAllRoutes,
  getMenus,
  getPlatformList
} from "@/api/menu";

const defaultModel = {
  id: "",
  parentId: "",
  parentName: "",
  component: "",
  name: "",
  title: "",
  code: "",
  type: 1,
  path: "",
  redirect: "",
  sort: 0,
  hasChildren: false,
  meta: {
    title: "",
    roles: [],
    affix: "",
    noCache: true,
    icon: ""
  },
  hidden: false,
  children: []
};

export default {
  filters: {
    typeFilter(type) {
      const typeMap = {
        1: "菜单",
        2: "按钮"
      };
      return typeMap[type];
    },
    cacheFilter(type) {
      const typeMap = {
        true: "是",
        false: "否"
      };
      return typeMap[type];
    }
  },
  data() {
    return {
      filterText: "",
      model: Object.assign({}, defaultModel),
      routes: [],
      allRoutes: [],
      dialogVisible: false,
      dialogType: "new",
      typeOptions: [1, 2],
      cacheOptions: [true, false],
      labelPosition: "right",
      activeName: "USER",
      viewModel: {
        page: 1,
        pageSize: 10,
        total: 0,
        OrderBy: "CreateTime",
        IsAsc: "",
        PlatformType: "USER",
        MenuId: ""
      },
      rules: {
        title: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
        component: [
          { required: true, message: "请输入组件地址", trigger: "blur" }
        ],
        path: [{ required: true, message: "请输入菜单路由", trigger: "blur" }]
      },
      tabs: []
    };
  },
  created() {
    // this.getRoutes();
    // this.getAllRoutes();
  },
  mounted() {
    this.getPlatformList();
  },
  methods: {
    async getPlatformList() {
      var res = await getPlatformList();
      if (res.code == 200) {
        this.tabs = res.data;
        this.activeName = this.tabs[0].id;
        this.viewModel.MenuId = this.activeName;
        this.getRoutes();
      }
    },
    handleClick(tab, event) {
      this.viewModel.MenuId = this.activeName;
      this.getRoutes();
    },
    async getRoutes() {
      // const res = await getRoutes();
      this.viewModel.MenuId = this.activeName;
      var res = await getMenus(this.viewModel);
      this.routes = res.data;
    },
    async getAllRoutes() {
      const res = await getAllRoutes();
      this.allRoutes = res.data;
    },
    refresh() {
      this.getRoutes();
    },
    handleDelete({ $index, row }) {
      if (row.children && row.children.length > 0) {
        this.$notify({
          title: "提示",
          message: "请先删除下面的子节点!",
          type: "warning",
          duration: 3000
        });
        return false;
      }
      this.$confirm("确认删除" + row.title + "?", "提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(async () => {
          await deleteMenu(row.id);
          this.$notify({
            title: "成功",
            type: "success",
            message: "操作成功!"
          });
          this.getRoutes();
        })
        .catch(err => {
          console.error(err);
        });
    },
    handleEdit(scope) {
      this.dialogType = "edit";
      this.dialogVisible = true;
      if (this.model.parentName == "/")
        this.model.parentName = this.tabs.filter(
          z => z.id == this.activeName
        )[0].title;
      this.model = deepClone(scope.row);
      this.$nextTick(() => {
        this.$refs["model"].clearValidate(); //清空上次的错误验证提示
      });
    },
    addTopNode() {
      this.model = Object.assign({}, defaultModel);
      this.model.parentId = "";
      this.model.parentName = "/";
      this.$nextTick(() => {
        this.$refs["model"].clearValidate(); //清空上次的错误验证提示
      });
      this.dialogType = "new";
      this.dialogVisible = true;
    },
    removeTab(targetName) {
      this.$confirm("确认删除?", "提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(async () => {
          await deleteMenu(targetName);
          this.$notify({
            title: "成功",
            type: "success",
            message: "操作成功!"
          });
          this.$router.go(0);
        })
        .catch(err => {
          console.error(err);
        });
    },
    addSubNode(scope) {
      this.model = Object.assign({}, defaultModel);
      this.model.parentId = scope.row.id;
      this.model.parentName = scope.row.title;
      this.model.meta.icon = "";
      this.$nextTick(() => {
        this.$refs["model"].clearValidate(); //清空上次的错误验证提示
      });
      this.dialogType = "new";
      this.dialogVisible = true;
    },
    async confirmModel() {
      //如果把验证失败弹出提示代码放在validate里面则不会弹出错误提示，直接走下面的更新操作代码
      var v;
      this.$refs["model"].validate(valid => {
        v = valid;
      });
      if (!v) {
        return false;
      }
      const isEdit = this.dialogType === "edit";
      this.model.name = this.model.code;
      var res;
      if (isEdit) {
        res = await updateMenu(this.model);
      } else {
        res = await addMenu(this.model);
      }
      if (res.code == 200) {
        this.dialogVisible = false;
        this.$notify({
          title: "成功",
          type: "success",
          message: "操作成功!"
        });
        if (
          this.model.parentId == "" ||
          this.model.parentId == "00000000-0000-0000-0000-000000000000"
        )
          this.getPlatformList();
        this.getRoutes();
      } else {
        this.$notify({
          title: "失败",
          type: "error",
          message: "操作失败"
        });
      }
    }
  }
};
</script>

<style scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 12px;
}
</style>
